home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #2 / Amiga Plus CD - 1995 - No. 2.iso / startrek / trek73 / src / moveships.c < prev    next >
C/C++ Source or Header  |  1995-04-11  |  8KB  |  384 lines

  1. /*
  2.  * TREK73: moveships.c
  3.  *
  4.  * Actual command execution
  5.  *
  6.  * move_ships
  7.  *
  8.  */
  9.  
  10. #include "defines.h"
  11. #include "structs.h"
  12.  
  13. extern int defenseless;
  14. extern int corbomite;
  15. extern int surrender;
  16. extern int surrenderp;
  17. extern char shutup[];
  18. extern int global;
  19. extern int reengaged;
  20.  
  21.  
  22. move_ships() {
  23.     extern    double sin();
  24.     extern    double cos();
  25.     extern    double sqrt();
  26.     extern    float fabs();
  27.     extern    struct list head;
  28.     extern    struct list *tail;
  29.     extern    int shipnum;
  30.     extern    struct ship *shiplist[];
  31.     register int i;
  32.     register int j;
  33.     register int k;
  34.     register struct list *lp;
  35.     register struct ship *sp;
  36.     struct    torpedo *tp;
  37.     struct    ship *fed;
  38.     struct    list *lp1;
  39.     struct    ship *sp1;
  40.     int    iterations;
  41.     float    tmpf;
  42.     int    course, newcourse, energy;
  43.     float    warp, newwarp;
  44.     int    x, y;
  45.     struct    ship *target;
  46.     int    kills, others, fedstatus;
  47.     struct    ship *ep;
  48.     double    d0;
  49.     extern    float    segment;
  50.     extern    float    timeperturn;
  51.     float    Mpersegment;
  52.  
  53.     /*
  54.      * The value 100 is the number of Megameters per second
  55.      * per warp-factor
  56.      */
  57.     Mpersegment = segment * 100.0;
  58.     iterations = timeperturn/segment;
  59.     for (i=0; i<=shipnum; i++)
  60.         distribute(shiplist[i]);
  61.     fed = shiplist[0];
  62.     for (i=0; i<iterations; i++) {
  63.         for (lp = &head; lp != NULL; lp = lp->fwd) {
  64.             if (lp == tail)
  65.                 break;
  66.             if (lp->type == 0)
  67.                 continue;
  68.             sp = NULL;
  69.             tp = NULL;
  70.             if (lp->type == I_SHIP)
  71.                 sp = lp->data.sp;
  72.             else
  73.                 tp = lp->data.tp;
  74.             if (sp && sp->status & S_DEAD)
  75.                 continue;
  76.             if (sp) {
  77.                 phaser_firing(sp);
  78.                 torpedo_firing(sp);
  79.             }
  80.             /*
  81.              * time fuses
  82.              */
  83.             if (tp) {
  84.                 tp->timedelay--;
  85.                 if (tp->timedelay <= 0) {
  86.                     torp_detonate(tp, lp);
  87.                     continue;
  88.                 }
  89.             } else {
  90.                 sp->delay--;
  91.                 if (sp->delay <= 0) {
  92.                     ship_detonate(sp, lp);
  93.                     continue;
  94.                 }
  95.             }
  96.             /*
  97.              * proximity fuse
  98.              */
  99.             if (tp && tp->prox != 0) {
  100.                 for (lp1 = &head; lp1 != tail; lp1 = lp1->fwd) {
  101.                     if (lp1->type != I_SHIP)
  102.                         continue;
  103.                     sp1 = lp1->data.sp;
  104.                     if (sp1 == tp->from)
  105.                         continue;
  106.                     j=rangefind(tp->x,sp1->x,tp->y,sp1->y);
  107.                     if (j > tp->prox)
  108.                         continue;
  109.                     torp_detonate(tp, lp);
  110.                     tp = 0;
  111.                     break;
  112.                 }
  113.                 if (!tp)
  114.                     continue;
  115.             }
  116.             /*
  117.              * movement simulation
  118.              */
  119.             if (sp && sp->status & S_DEAD)
  120.                 continue;
  121.             if (sp) {
  122.                 x = sp->x;
  123.                 y = sp->y;
  124.                 warp = sp->warp;
  125.                 newwarp = sp->newwarp;
  126.                 course = sp->course;
  127.                 newcourse = sp->newcourse;
  128.                 target = sp->target;
  129.                 energy = sp->energy;
  130.                 /*
  131.                  * fuel consumption
  132.                  */
  133.                 if (fabs((double) warp) >= 1)
  134.                     j = (int) (warp * sp->eff * segment);
  135.                 else
  136.                     j = 0;
  137.                 if (j < 0)
  138.                     j *= -1;
  139.                 if (j > energy) {
  140.                     if (!shutup[BURNOUT + sp->id]  && !(sp->status & S_WARP)) {
  141.                         printf("%s's warp drive burning out.\n",
  142.                             sp->name);
  143.                         shutup[BURNOUT + sp->id]++;
  144.                     }
  145.                     newwarp = warp < 0 ? -.99 : .99;
  146.                     energy = 0;
  147.                 } else
  148.                     energy -= j;
  149.             } else {
  150.                 x = tp->x;
  151.                 y = tp->y;
  152.                 warp = tp->speed;
  153.                 newwarp = tp->newspeed;
  154.                 course = tp->course;
  155.                 newcourse = course;
  156.                 target = tp->target;
  157.             }
  158.             /*
  159.              * destroyed warp drive
  160.              */
  161.             if (sp && (sp->status & S_WARP))
  162.                 if (fabs((double)warp) > 1.0)
  163.                     newwarp = warp < 0.0 ? -.99 : .99;
  164.             /*
  165.              * automatic pilot
  166.              */
  167.             if (target != NULL) {
  168.                 if (sp && (target->status & S_DEAD)) {
  169.                     if ((sp == fed) && (!shutup[DISENGAGE]) && !(sp->status & S_DEAD))
  170.                         printf("%s's autopilot disengaging.\n",
  171.                         sp->name);
  172.                     newcourse = course;
  173.                     shutup[DISENGAGE]++;
  174.                     target = NULL;
  175.                     sp->eluding = 0;
  176.                 } else {
  177.                     j = bearing(x, target->x, y, target->y);
  178.                     if (sp && sp->eluding)
  179.                         j = rectify(j + 180);
  180.                     newcourse = (float) j;
  181.                     /*if ((sp) && (sp != fed)) {
  182.                         sp->newwarp = 1.0;
  183.                         newwarp = 1.0;
  184.                     }*/
  185.                     if (tp)
  186.                         course = newcourse;
  187.                 }
  188.             }
  189.             /*
  190.              * turn rate
  191.              */
  192.             if (course != newcourse) {
  193.                 j = rectify(newcourse - course);
  194.                 if (j > 180)
  195.                     j -= 360;
  196.                 /*
  197.                  * maximum degrees turned in one turn
  198.                  */
  199.                 k = (int) ((12.0 - warp) * 4.0 * segment);
  200.                 if (sp->status & S_WARP)
  201.                     k /= 2;
  202.                 k = (int) course + (j < 0 ? -1 : 1) *
  203.                     min(abs(j), k);
  204.                 course = (float) rectify(k);
  205.             }
  206.             /*
  207.              * acceleration
  208.              */
  209.             tmpf = newwarp - warp;
  210.             if (tmpf < 0.0)
  211.                 d0 = (double) (tmpf * -1.0);
  212.             else
  213.                 d0 = (double) tmpf;
  214.             if (tmpf != 0.0)
  215.                 warp += (tmpf < 0 ? -1 : 1) * sqrt(d0)
  216.                     * segment;
  217.             d0 = (double) toradians(course);
  218.             x += (int) (warp * cos(d0) * Mpersegment);
  219.             y += (int) (warp * sin(d0) * Mpersegment);
  220.             if ((warp > -0.1) && (warp < 0.1)){
  221.                 warp = 0.0;
  222.             }
  223.             /*
  224.              * reset all the vars
  225.              */
  226.             if (sp) {
  227.                 sp->x = x;
  228.                 sp->y = y;
  229.                 sp->warp = warp;
  230.                 sp->newwarp = newwarp;
  231.                 sp->course = course % 360;
  232.                 sp->newcourse = newcourse % 360;
  233.                 sp->energy = energy;
  234.                 sp->target = target;
  235.             } else {
  236.                 tp->x = x;
  237.                 tp->y = y;
  238.                 tp->speed = warp;
  239.                 tp->course = course % 360;
  240.                 tp->target = target;
  241.             }
  242.         }
  243.     }
  244.     for (i=0; i <= shipnum; i++) {        /* Check targets */
  245.         sp = shiplist[i];
  246.         if (sp->status & S_DEAD)
  247.             continue;
  248.         for (j=0; j<4; j++) {
  249.             target = sp->phasers[j].target;
  250.             if (target && (target->status & S_DEAD)) {
  251.                 if ((sp == fed) && (!shutup[PHASERS+j])&& !(sp->status & S_DEAD))
  252.                     printf("  phaser %d disengaging\n",j+1);
  253.                 sp->phasers[j].target = NULL;
  254.                 shutup[PHASERS+j]++;
  255.             }
  256.         }
  257.         for (j=0; j<6; j++) {
  258.             target = sp->tubes[j].target;
  259.             if (target && (target->status & S_DEAD)) {
  260.                 if ((sp == fed) && (!shutup[TUBES+j]) && !(sp->status & S_DEAD))
  261.                     printf("  tube %d disengaging\n", j+1);
  262.                 sp->tubes[j].target = NULL;
  263.                 shutup[TUBES+j]++;
  264.             }
  265.         }
  266.     }
  267.     /*
  268.      * self-destruct warning
  269.      */
  270.     if ((fed->delay < 1000) && (fed->delay > 8)) {
  271.         printf("Computer:   %d seconds to self destruct.\n",fed->delay/9);
  272.     } 
  273.     /*
  274.      * Ruses, bluffs, surrenders
  275.      */
  276.     if (defenseless)
  277.         defenseless++;
  278.     if (corbomite)
  279.         corbomite++;
  280.     if (surrender)
  281.         surrender++;
  282.     if (surrenderp)
  283.         surrenderp++;
  284.     /*
  285.      * Federation dispostion
  286.      */
  287.     sp = fed;
  288.     kills = others = fedstatus = 0;
  289.     if ((sp->crew <= 0) || (sp->status & S_DEAD)) {
  290.         fedstatus = 1;
  291.         sp->status |= S_DEAD;
  292.     } else
  293.         for (j=0; j<1; j++) {
  294.             for (i=0; i<4; i++)
  295.                 if (~sp->phasers[i].status | ~P_DAMAGED)
  296.                     break;
  297.             if (i != 4)
  298.                 continue;
  299.             for (i=0; i<6; i++)
  300.                 if (~sp->tubes[i].status | ~T_DAMAGED)
  301.                     break;
  302.             if (i != 6)
  303.                 continue;
  304.             fedstatus = 1;
  305.         }
  306.     /*
  307.      * enemy disposition
  308.      */
  309.     for (k=1; k <= shipnum; k++) {
  310.         ep = shiplist[k];
  311.         if (ep->status & S_DEAD) {
  312.             kills++;
  313.             continue;
  314.         }
  315.         if (ep->crew <= 0) {
  316.             ep->status |= S_DEAD;
  317.             kills++;
  318.             continue;
  319.         }
  320.         if (fedstatus)
  321.             continue;
  322.         j = rangefind(sp->x, ep->x, sp->y, ep->y);
  323.         if ((j>3500 && (ep->status & S_WARP)) ||
  324.             (j>4500 && ep->delay<100)) {
  325.                 others++;
  326.                 continue;
  327.         }
  328.         /* Check if we are within range to turn off the flag */
  329.         if ((j <= 3500) && (reengaged))
  330.             reengaged = 0;
  331.         if (ep->energy > 10)
  332.             continue;
  333.         for (i=0; i<4; i++)
  334.             if (~ep->phasers[i].status | ~P_DAMAGED)
  335.                 break;
  336.         if (i != 4)
  337.             continue;
  338.         for (i=0; i<6; i++)
  339.             if (~ep->tubes[i].status | ~T_DAMAGED)
  340.                 break;
  341.         if (i != 6)
  342.             continue;
  343.         kills++;
  344.     }
  345.     if (fedstatus == 0 && (global & E_SURRENDER)) {
  346.         if (leftovers())
  347.             warn(4);
  348.         else {
  349.             final(4);
  350.         }
  351.     }
  352.     if ((fed->status & S_SURRENDER) && (kills + others < shipnum)) {
  353.         if (leftovers())
  354.             warn(3);
  355.         else {
  356.             final(3);
  357.         }
  358.     }
  359.     if (fedstatus == 0 && kills+others < shipnum)
  360.         return 0;
  361.     if (fedstatus == 1 && kills+others < shipnum) {
  362.         if (leftovers())
  363.             warn(0);
  364.         else
  365.             final(0);
  366.     }
  367.     if (fedstatus == 0 && kills == shipnum) {
  368.         if (leftovers())
  369.             warn(1);
  370.         else
  371.             final(1);
  372.     }
  373.     if (fedstatus == 0 && kills+others == shipnum) {
  374.         if (leftovers())
  375.             warn(2);
  376.         else
  377.             final(2);
  378.     }
  379.     if (fedstatus == 1 && kills == shipnum) {
  380.         final(5);
  381.     }
  382.     return 0;
  383. }
  384.